package com.taobao.sinan.dal.loader;

import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;

public abstract class ClassLoaderUtil {
	private static Map<String, ClassLoader> CLASS_lOADER_CACHE = new HashMap<String, ClassLoader>();

	private ClassLoaderUtil() {
	}

	public static Class<?> loadClass(String clazz, File appPath) throws Exception {
		Class<?> cls = null;
		try {
			ClassLoader cl = getClassLoader(appPath.getName());

			try {
				if (cl != null) {
					cls = cl.loadClass(clazz);
				}
			} catch (Exception e) {
				
			}

			if (cls == null) {
				cl = getCommonClassLoader();
				cls = cl.loadClass(clazz);
			}
		} catch (Exception e) {
			cls = Class.forName(clazz);
		}

		return cls;
	}

	private static ClassLoader getCommonClassLoader() {
		return getClassLoader("");
	}

	private static ClassLoader getClassLoader(String app) {
		if (CLASS_lOADER_CACHE.containsKey(app)) {
			return CLASS_lOADER_CACHE.get(app);
		}

		ClassLoader cl = null;
		File path = new File(Constants.BASE_PATH, app + "/" + Constants.LIB);
		if (path.exists() && path.isDirectory()) {
			File[] files = path.listFiles(new FileFilter() {
				@Override
				public boolean accept(File pathname) {
					String name = pathname.getName().toLowerCase();
					return pathname.isFile() && name.endsWith(".jar");
				}
			});

			URL[] urls = new URL[files.length + 1];
			try {
				if (files.length > 0) {
					for (int i = 0; i < files.length; i++) {
						urls[i] = files[i].toURI().toURL();
					}
				}

				urls[files.length] = path.toURI().toURL();
				cl = URLClassLoader.newInstance(urls, Thread.currentThread().getContextClassLoader());
			} catch (Exception e) {
			}
		}

		CLASS_lOADER_CACHE.put(app, cl);
		return cl;
	}
}